# -*- coding: utf-8 -*-
"""
远程文件显示下载功能界面模块
实现远程设备连接和文件管理功能
"""

from datetime import datetime
from pathlib import Path
from PySide2.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QLabel, 
    QTableView, QHeaderView, QMenu, QMessageBox, QSplitter,
    QAbstractItemView, QFrame, QAction, QStatusBar
)
from PySide2.QtCore import Qt, Signal, QTimer
from PySide2.QtGui import QDragEnterEvent, QDropEvent, QIcon
from gglobal import logger
from ..models.filetree_model import FileTreeModel, FileInfo
from .property_button import ScanButton, ConnectButton
from .progressinfo_widget import ProgressInfoWidget
from ..handlercore.networkscan_manager import NetworkScanManager
from ..handlercore.vehicle_connection_manager import VehicleConnectionManager
from ..handlercore.file_manager import FileManager
from ..handlercore.language_manager import LanguageManager
from ..handlercore.car_reconnect import CarReconnectManager
from ..handlercore.theme_manager import ThemeManager
from .custom_combo_box import CustomComboBox



class RemoteFileView(QWidget):
    """远程文件显示下载功能界面类"""
    
    def __init__(self, parent=None, vehicle_connection_manager=None, should_disconnect_on_close=True):
        super().__init__(parent)
        self.setObjectName("remote_file_view")
        
        # 初始化组件
        self.language_manager = LanguageManager()
        self.theme_manager = ThemeManager()
        
        # 初始化管理器
        self.network_scan_manager = NetworkScanManager(self)
        # 支持外部注入的连接管理器，未提供则创建新的
        self.vehicle_connection_manager = vehicle_connection_manager or VehicleConnectionManager(self)
        self.file_manager = FileManager(self)
        self.car_reconnect_manager = CarReconnectManager(self.language_manager, self)
        
        # 关闭行为控制：True=关闭窗口时强制断开；False=仅释放持有者
        self.should_disconnect_on_close = should_disconnect_on_close
        
        # 初始化文件模型
        self.file_model = self.file_manager.get_file_model()
        
        # 初始化进度窗口
        self.progress_widget = None
        
        # 登记连接持有者，避免误断开（如果用户选择非强制断开）
        try:
            if hasattr(self.vehicle_connection_manager, 'acquire'):
                self.vehicle_connection_manager.acquire(self)
        except Exception as e:
            logger.warning(f"登记连接持有者失败: {e}")
        
        self.init_ui()
        self.setup_connections()
        self.setup_manager_connections()
        self.setup_language()  # 设置语言支持
        
        # self.setup_sample_data()  # 添加示例数据
        logger.info("远程文件视图初始化完成")
        
    def init_ui(self):
        """初始化用户界面"""
        #设置窗口尺寸
        self.setMinimumSize(1200, 800)
        # 创建主布局
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(10, 10, 10, 10)
        main_layout.setSpacing(10)
        
        # 创建网段控制区域
        self.create_network_area(main_layout)
        
        # 创建连接控制区域
        self.create_connection_area(main_layout)
        
        # 创建分隔线
        separator = QFrame()
        separator.setFrameShape(QFrame.HLine)
        separator.setFrameShadow(QFrame.Sunken)
        main_layout.addWidget(separator)
        
        # 创建文件列表区域
        self.create_file_list_area(main_layout)
        
        # 创建状态栏
        self.create_status_bar(main_layout)
        
    def create_connection_area(self, parent_layout):
        """创建连接控制区域"""
        # 连接控制布局
        connection_layout = QHBoxLayout()
        connection_layout.setSpacing(10)
        
        # 车辆IP标签
        self.ip_label = QLabel()
        self.ip_label.setObjectName("vehicle_ip_label")
        connection_layout.addWidget(self.ip_label)
        
        # IP列表下拉框
        current_theme = self.theme_manager.get_current_theme_name()
        self.ip_combo = CustomComboBox(theme=current_theme)
        self.ip_combo.setEditable(True)
        self.ip_combo.setMinimumWidth(355)
        
        # IP输入校验已移至NetworkScanManager
        connection_layout.addWidget(self.ip_combo)
        
        # 连接按钮
        self.connect_button = ConnectButton()
        self.connect_button.setObjectName("connect_button")
        self.connect_button.setMinimumSize(80, 32)
        connection_layout.addWidget(self.connect_button)
        
        # 添加弹性空间
        connection_layout.addStretch()
        
        parent_layout.addLayout(connection_layout)
        
    def create_network_area(self, parent_layout):
        """创建网段控制区域"""
        # 网段控制布局
        network_layout = QHBoxLayout()
        network_layout.setSpacing(10)
        
        # 网段标签
        self.network_label = QLabel()
        self.network_label.setObjectName("network_label")
        network_layout.addWidget(self.network_label)
        
        # 网段输入框列表
        current_theme = self.theme_manager.get_current_theme_name()
        self.network_combo = CustomComboBox(theme=current_theme)
        self.network_combo.setEditable(True)
        self.network_combo.setMinimumWidth(200)
        
        # 网段输入校验已移至NetworkScanManager
        network_layout.addWidget(self.network_combo)
        
        # 本机网段按钮
        self.local_network_button = ConnectButton()
        self.local_network_button.setObjectName("local_network_button")
        self.local_network_button.setMinimumSize(100, 32)
        network_layout.addWidget(self.local_network_button)
        
        # 扫描车辆按钮
        self.scan_button = ScanButton()
        self.scan_button.setObjectName("scan_button")
        self.scan_button.setMinimumSize(80, 32)
        network_layout.addWidget(self.scan_button)
        
        # 添加弹性空间
        network_layout.addStretch()
        
        parent_layout.addLayout(network_layout)
        
    def create_file_list_area(self, parent_layout):
        """创建文件列表区域"""
        # 文件列表视图
        self.file_table = QTableView()
        self.file_table.setObjectName("file_table")
        
        parent_layout.addWidget(self.file_table)
        
    def create_status_bar(self, parent_layout):
        """创建状态栏"""
        self.status_bar = QStatusBar()
        self.status_bar.setObjectName("remote_file_status_bar")
        # 设置初始状态
        ready_text = self.language_manager.get_constant('status_ready')
        self.status_bar.showMessage(ready_text)
        parent_layout.addWidget(self.status_bar)
        
    def setup_connections(self):
        """设置基本信号连接"""
        # 设置管理器的UI组件
        self.network_scan_manager.set_ui_components(
            self.network_combo, self.ip_combo, 
            self.scan_button, self.local_network_button
        )
        
        # 连接本地网段更新信号
        self.network_scan_manager.local_networks_updated.connect(self.network_scan_manager._on_local_networks_updated)
        
        self.vehicle_connection_manager.set_ui_components(
            self.connect_button, self.status_bar
        )
        
        self.file_manager.set_ui_components(self.file_table)
        
        logger.info("信号连接设置完成")
        
    def setup_manager_connections(self):
        """设置管理器信号连接"""
        
        # 车辆连接管理器信号连接 - 只连接核心管理信号
        self.vehicle_connection_manager.connection_status_changed.connect(self.on_connection_status_changed)
        self.vehicle_connection_manager.command_output.connect(self.on_command_output)
        # 文件管理器信号连接
        self.file_manager.operation_completed.connect(self.on_operation_completed)
        self.file_manager.operation_completed_message.connect(self.show_operation_result)
        self.file_manager.selection_changed.connect(self.on_selection_changed)
        self.file_manager.navigation_changed.connect(self.on_navigation_changed)
        
    def setup_language(self):
        """设置语言支持"""
        # 注册UI控件到语言管理器
        self.language_manager.register_widget(self.network_label, "network_label")
        self.language_manager.register_widget(self.ip_label, "vehicle_ip_label")
        self.language_manager.register_widget(self.local_network_button, "local_network_button")
        self.language_manager.register_widget(self.scan_button, "scan_button")
        self.language_manager.register_widget(self.connect_button, "connect_button")
        
        # 连接语言切换信号
        self.language_manager.language_changed.connect(self.on_language_changed)
        
        logger.info("语言支持设置完成")
        
    def on_language_changed(self, language_text):
        """语言切换处理"""
        # 更新下拉框的占位符文本
        self.update_combo_placeholders()
        logger.info(f"语言已切换: {language_text.get('name', '')}")
        
    def update_combo_placeholders(self):
        """更新下拉框占位符文本"""
        self.network_scan_manager.update_combo_placeholders()

            
    def on_connection_status_changed(self, is_connected, message):
        """连接状态变化处理 - 简化版本，主要逻辑已移至VehicleConnectionManager"""
        logger.info(f"收到连接状态变化信号: connected={is_connected}, message={message}")
        
        if is_connected:
            # 连接成功时，将client_thread设置到file_manager中
            client_thread = self.vehicle_connection_manager.get_client_thread()
            if client_thread:
                self.file_manager.set_client_thread(client_thread)
                # 连接传输进度信号
                self.setup_transfer_progress_signals(client_thread)
                logger.info("客户端线程已成功设置到文件管理器")
            else:
                logger.warning("无法获取客户端线程，文件管理器未设置客户端线程")
        else:
            # 连接断开时，清除file_manager中的client_thread
            self.file_manager.set_client_thread(None)
            # 断开传输进度信号连接
            self.disconnect_transfer_progress_signals()
            logger.info("已清除文件管理器中的客户端线程")
            
            if "连接已断开" in message and "手动断开连接" not in message:
                # 只有连接异常断开时才显示重连弹窗，手动断开不显示
                self.car_reconnect_manager.process_reconnection_request(message, self.file_manager, self.vehicle_connection_manager)    
    

    
    def on_command_output(self, output):
        """命令输出处理"""
        logger.info(f"命令输出: {output}")
    
    def on_header_clicked(self, logical_index):
        """表头点击处理 - 实现排序功能"""
        # 委托给FileManager处理
        self.file_manager.handle_header_clicked(logical_index)
           
    def on_selection_changed(self, selected_files):
        """选择改变处理"""
        logger.debug(f"选择了 {len(selected_files)} 个文件")
        
    def on_navigation_changed(self, path):
        """导航路径变化处理"""
        # 更新UI中的路径显示
        logger.info(f"当前路径: {path}")
        self.status_bar.showMessage(path)
    
    def on_operation_completed(self, operation_type, success):
        """操作完成处理"""
        if success:
            message = self.language_manager.get_text(f"operation_success_{operation_type}", "操作成功")
        else:
            message = self.language_manager.get_text(f"operation_failed_{operation_type}", "操作失败")
        self.status_bar.showMessage(message)
    

    
    def show_operation_result(self, operation_type, success_files, failed_files):
        """显示操作结果的通用函数
        
        参数:
            operation_type: 操作类型 (upload, download, delete, extract, compress)
            success_files: 成功处理的文件列表
            failed_files: 失败的文件列表
        """
        # 操作类型的中文映射
        operation_names = {
            "upload": "上传",
            "download": "下载", 
            "delete": "删除",
            "extract": "解压",
            "compress": "压缩"
        }
        
        operation_name = operation_names.get(operation_type, operation_type)
        
        # 构建详细的操作结果信息
        result_message = f"文件{operation_name}操作完成\n\n"
        
        if success_files:
            result_message += f"✅ {operation_name}成功 ({len(success_files)} 个文件):\n"
            for file in success_files:
                result_message += f"  • {file}\n"
            result_message += "\n"
        
        if failed_files:
            result_message += f"❌ {operation_name}失败 ({len(failed_files)} 个文件):\n"
            for file in failed_files:
                result_message += f"  • {file}\n"
            result_message += "\n"
        
        # 添加总结信息
        total_files = len(success_files) + len(failed_files)
        result_message += f"总计: {total_files} 个文件，成功 {len(success_files)} 个，失败 {len(failed_files)} 个"
        
        # 根据结果选择合适的消息框类型
        title = f"{operation_name}文件结果"
        if failed_files:
            QMessageBox.warning(self, title, result_message)
        else:
            QMessageBox.information(self, title, result_message)
        
        logger.info(f"文件{operation_name}结果 - 成功: {success_files}, 失败: {failed_files}")
        
    def setup_transfer_progress_signals(self, client_thread):
        """设置传输进度信号连接
        
        Args:
            client_thread: 客户端线程对象
        """
        if hasattr(client_thread, 'transfer_progress'):
            client_thread.transfer_progress.connect(self.on_transfer_progress)
            logger.info("传输进度信号连接成功")
        else:
            logger.warning("客户端线程不支持transfer_progress信号")
            
    def disconnect_transfer_progress_signals(self):
        """断开传输进度信号连接"""
        client_thread = self.vehicle_connection_manager.get_client_thread()
        if client_thread and hasattr(client_thread, 'transfer_progress'):
            try:
                # 首先尝试具体槽函数断开连接
                try:
                    client_thread.transfer_progress.disconnect(self.on_transfer_progress)
                    logger.info("传输进度信号断开成功")
                except (TypeError, RuntimeError):
                    # 如果具体槽函数断开失败，尝试断开所有连接
                    client_thread.transfer_progress.disconnect()
                    logger.info("使用通用方法断开传输进度信号成功")
            except Exception as e:
                logger.warning(f"断开传输进度信号时发生异常: {e}")
                
        # 关闭进度窗口
        if self.progress_widget and self.progress_widget.isVisible():
            self.progress_widget.close()
            self.progress_widget = None
            
    def on_transfer_progress(self, filename, transferred, total, speed):
        """传输进度更新处理
        
        Args:
            filename: 文件名
            transferred: 已传输字节数
            total: 总字节数
            speed: 传输速度（字节/秒）
        """
        # 如果进度窗口不存在或已关闭，创建新的进度窗口
        if not self.progress_widget or not self.progress_widget.isVisible():
            self.show_progress_window(filename)
            
        # 更新进度
        if self.progress_widget:
            self.progress_widget.update_progress(filename, transferred, total, speed)
            
            # 如果传输完成，自动关闭进度窗口
            if transferred >= total and total > 0:
                QTimer.singleShot(2000, self.close_progress_window)  # 2秒后自动关闭
                
        # logger.debug(f"传输进度更新: {filename} - {transferred}/{total} - {speed} B/s")
        
    def show_progress_window(self, filename):
        """显示进度窗口
        
        Args:
            filename: 文件名
        """
        # 如果进度窗口不存在，创建新的实例
        if not self.progress_widget:
            self.progress_widget = ProgressInfoWidget(self)
            
            # 连接取消信号（只在创建时连接一次）
            try:
                self.progress_widget.cancel_requested.connect(self.on_transfer_cancel_requested)
                logger.debug("进度窗口取消信号连接成功")
            except Exception as e:
                logger.error(f"进度窗口取消信号连接失败: {e}")
        else:
            # 如果窗口已存在，重置状态以便重复使用
            self.progress_widget.reset_for_reuse()
        
        # 确定操作类型（简单判断，可以根据实际需要改进）
        operation_type = "传输"  # 默认为传输，可以根据实际情况判断
        
        # 开始传输
        self.progress_widget.start_transfer(filename, operation_type)
        
        # 显示窗口（居中显示）
        self.progress_widget.show()
        
        # 将窗口移动到父窗口中心
        parent_geometry = self.geometry()
        widget_geometry = self.progress_widget.geometry()
        x = parent_geometry.x() + (parent_geometry.width() - widget_geometry.width()) // 2
        y = parent_geometry.y() + (parent_geometry.height() - widget_geometry.height()) // 2
        self.progress_widget.move(x, y)
        
        logger.info(f"显示传输进度窗口: {filename}")
        
    def close_progress_window(self):
        """关闭进度窗口"""
        if self.progress_widget and self.progress_widget.isVisible():
            self.progress_widget.finish_transfer(success=True)
            
            # 使用QTimer延迟隐藏窗口，但不删除对象以便重复使用
            def delayed_hide():
                if self.progress_widget:
                    self.progress_widget.hide()
                    
            QTimer.singleShot(1000, delayed_hide)
            logger.info("隐藏传输进度窗口")
            
    def on_transfer_cancel_requested(self):
        """传输取消请求处理"""
        logger.info("用户请求取消传输")
        
        # 停止当前的文件传输操作
        if self.file_manager:
            self.file_manager._stop_current_worker()
            logger.info("已停止当前传输操作")
        
        # 关闭进度窗口
        if self.progress_widget:
            self.progress_widget.finish_transfer(success=False, message="用户取消")
            
            # 使用QTimer延迟隐藏窗口，但不删除对象以便重复使用
            def delayed_hide():
                if self.progress_widget:
                    self.progress_widget.hide()
                    
            QTimer.singleShot(1000, delayed_hide)
            
    def closeEvent(self, event):
        """窗口关闭事件处理"""
        logger.info("开始关闭远程文件视图窗口")
        
        try:
            # 1. 停止当前的文件传输操作
            if self.file_manager:
                self.file_manager._stop_current_worker()
                logger.info("已停止文件管理器中的工作线程")
            
            # 2. 处理车辆连接：根据标志决定断开或释放
            if self.vehicle_connection_manager:
                if getattr(self, 'should_disconnect_on_close', True):
                    # 保持原行为：强制断开（将产生“手动断开连接”消息）
                    self.vehicle_connection_manager.disconnect_from_vehicle()
                    logger.info("已断开车辆连接")
                else:
                    # 安全释放持有者，不强制断开（若无其他持有者且仍连接，将自动断开）
                    if hasattr(self.vehicle_connection_manager, 'release'):
                        self.vehicle_connection_manager.release(self)
                        logger.info("释放连接持有者，不强制断开")
            
            # 3. 停止网络扫描
            if self.network_scan_manager:
                # 停止扫描线程
                if hasattr(self.network_scan_manager, '_scan_thread') and self.network_scan_manager._scan_thread:
                    if self.network_scan_manager._scan_thread.isRunning():
                        self.network_scan_manager._scan_thread.stop_scan()
                        self.network_scan_manager._scan_thread.wait(3000)  # 等待最多3秒
                        logger.info("已停止网络扫描线程")
            
            # 4. 断开传输进度信号连接
            self.disconnect_transfer_progress_signals()
            
            # 5. 关闭进度窗口
            if self.progress_widget:
                try:
                    # 断开信号连接
                    self.progress_widget.cancel_requested.disconnect()
                except (TypeError, RuntimeError):
                    pass  # 信号可能已经断开
                
                if self.progress_widget.isVisible():
                    self.progress_widget.close()
                self.progress_widget.deleteLater()
                self.progress_widget = None
                logger.info("已关闭进度窗口")
            
            # 6. 清理重连管理器
            if self.car_reconnect_manager:
                # 断开重连管理器的信号连接
                try:
                    self.car_reconnect_manager.reconnection_completed.disconnect()
                except (TypeError, RuntimeError):
                    pass  # 信号可能已经断开
                logger.info("已清理重连管理器")
            
            logger.info("远程文件视图窗口关闭清理完成")
            
        except Exception as e:
            logger.error(f"关闭窗口时发生异常: {e}")
        finally:
            # 确保调用父类的closeEvent
            super().closeEvent(event)


    def setup_sample_data(self):
        """设置示例数据"""
        from datetime import timedelta
        
        base_time = datetime.now()
        sample_files = [
            FileInfo("documents", 0, base_time - timedelta(days=5), "drwxr-xr-x", "user", True),
            FileInfo("logs", 0, base_time - timedelta(days=2), "drwxr-xr-x", "admin", True),
            FileInfo("config.txt", 1024, base_time - timedelta(hours=3), "-rw-r--r--", "user"),
            FileInfo("data.log", 2048576, base_time - timedelta(days=1), "-rw-r--r--", "admin"),
            FileInfo("backup.zip", 10485760, base_time - timedelta(hours=12), "-rw-r--r--", "user"),
            FileInfo("image.jpg", 512000, base_time - timedelta(minutes=30), "-rw-r--r--", "guest"),
            FileInfo("video.mp4", 104857600, base_time, "-rw-r--r--", "admin"),
            FileInfo("readme.md", 2048, base_time - timedelta(days=3), "-rw-r--r--", "user"),
        ]
        
        self.file_manager.set_files(sample_files, "/home/user")